<template>
  <div class="table" ref="tableContainer">
    <a-table :id="`table${uuid}`" :dataSource="treeTableData" :align="center" :size="props.size" :columns="tableColumns"
      @change="onChange" :row-selection="props.rowSelection" @expand="expand" :rowKey="rowKey"
      :pagination="pagination.total ? pagination : false" :scroll="cancelScroll ? null : scrollDefault"
      :bordered="bordered" :showSelection="props.showSelection" class="ant-table-wrapper"
      :defaultExpandAllRows="defaultExpandAllRows" :showSorterTooltip="props.showSorterTooltip" :customRow="rowClick">
      <template #headerCell="{ title, column }">
        <template v-if="column.icon">
          <span :class="['iconfont', column.icon]"></span>
          {{ column.title }}
        </template>

        <template v-if="column.required">
          <span class="xing">*</span>
          {{ column.title }}
        </template>
        <slot name="headerCell" :column="column" :title="title"> </slot>
      </template>

      <template #bodyCell="{ column, text, record, index }">
        <slot name="editSlot" :column="column" :text="text" :record="record" :index="index">
        </slot>
      </template>

      <template #expandedRowRender="{ column, text, record, index }" v-if="props.isInnerTable">
        <slot name="innerTable" :column="column" :text="text" :record="record" :index="index"></slot>
      </template>

      <template v-if="props.filtrateSlot" #filterDropdown="{
          setSelectedKeys,
          selectedKeys,
          confirm,
          clearFilters,
          column,
          
        }">
        <slot name="filterDropdown" :setSelectedKeys="setSelectedKeys" :selectedKeys="selectedKeys" :confirm="confirm"
          :clearFilters="clearFilters" :column="column"></slot>
      </template>

      <template #emptyText v-if="props.dataSource.length == 0">
        <img src="../../styles/img/nullTable.png" alt="" class="null-iamge" />
        <div class="null-text">暂无数据</div>
      </template>
    </a-table>

    <!-- 分页 -->
    <Pagination v-if="isPagination && page.total" :page="page" @pageChange="pageChange">
    </Pagination>
  </div>
</template>

<script setup>
import Pagination from "./component/Pagination.vue";
import Sortable from "sortablejs";
import { guid } from "@/util/stringUtil.js";
import { ref, watch, onMounted, nextTick, h, onUnmounted } from "vue";
import {
  setTreeStyle,
  transverseNode,
  getFlatNode,
  getElIndex,
  getTreeData,
  deleteEl,
  getBrotherNodes
} from "./method.js";
import { message } from "ant-design-vue";

const uuid = ref(guid());

const emit = defineEmits([
  "change",
  "onDeviceList",
  "pageChange",
  "drag",
  "expandTable",
  "customRow",
  "tabSort",
  "dragSortTable"
]);
const props = defineProps({
  dataSource: Array,
  goColumns: Array, //被访问
  comeColumns: Array, //访问
  columns: Array,
  scroll: Object,
  rowSelection: Object,
  rowKey: {
    type: String,
    default: 'id'
  },
  sortTableID: String,
  sortTabModuleId: null,
  pagination: {
    type: Object,
    default: {},
  },
  isInnerTable: {
    type: Boolean,
    default: false,
  },
  isPagination: {
    type: Boolean,
    default: false,
  },
  page: {
    type: Object,
    default: {}
  },
  center: {
    type: String,
    default: "center"
  },
  showSelection: {
    //是否启用拖拽排序
    type: Boolean,
    default: true,
  },
  filtrateSlot: {
    type: Boolean,
    default: false,
  },
  isTreeData: {
    type: Boolean,
    default: false,
  },
  showSerial: {
    type: Boolean,
    default: true,
  },
  serialWidth: {
    type: Number,
    default: 110,
  },
  bordered: {
    type: Boolean,
    default: false,
  },
  cancelScroll: {
    type: Boolean,
    default: false,
  },
  sortComponentName: {
    type: String,
    default: "",
  },
  defaultExpandAllRows: {
    type: Boolean,
    default: false,
  },
  showSorterTooltip: {
    type: Boolean,
    default: false,
  },
  size: {
    type: String,
    default: "default",
  },
});

const onChange = (pagination, filters, sorter, { currentDataSource }) => {
  emit("change", pagination, filters, sorter, { currentDataSource });
};

const pageChange = (pageIndex, pageSize) =>
  emit("pageChange", pageIndex, pageSize);
// 默认值
const tableContainer = ref(null);
const treeTableData = ref([]);
const flatTreeData = ref([]);
// 树形结构添加序号
let serial = 0;
const setData = (val, level) => {
  if (!val || !val.length) return;
  val.forEach((item) => {
    item.serial = ++serial;
    if (item.children && item.children.length) {
      setData(item.children, level + 1);
    }
  });
};

const tableColumns = ref([]);
// const handleResizeColumn =  (w, col) => {
//   col.width = w;
// }

watch(
  () => props.columns,
  (val) => {
    tableColumns.value = [...val];
    tableColumns.value = tableColumns.value.map((item) => {
      item.ellipsis = true;
      return item;
    });
    if (props.showSerial) {
      tableColumns.value.unshift({
        dataIndex: "serial",
        title: "序号",
        width: props.serialWidth,
        fixed: "left",
        customRender({ text, record, index, column }) {
          // 权限
          const permission = [
            "organizationSort",
            "managerSort",
            "companySort",
            "companyAreaSort",
            "regionSort",
            "meterStoreSort",
            "paymentBusinessSort",
            "accountSort",
            "costItemSort",
            "pricePropSort",
            "waterPriceSort",
            "sysMenuSort",
            "sysModuleSort",
            "professionIsSort",
          ];
          if (record.isShow || !props.sortComponentName) {
            const moveIcon = `<i class="iconfont up-Sort moveSort"></i>`;
            const el = `${props.showSelection && !record.moveSort ? moveIcon : ""
              } ${record.serial} `;
            return h("div", {
              innerHTML: el,
            });
          }
          if (permission.includes(props.sortComponentName)) {
            const moveIcon = `<i class="iconfont up-Sort moveSort"></i>`;
            const el = `${props.showSelection && !record.moveSort ? moveIcon : ""
              } ${record.serial} `;
            return h("div", {
              innerHTML: el,
            });
          }
        },
      });
    }

  },
  {
    deep: true,
    immediate: true,
  }
);

// 排序
let newIndex, oldIndex;
const initSortable = () => {
  if (!props.showSelection) return;
  nextTick(() => {
    const tableEl = document.querySelector(`#table${uuid.value}`);
    if (!tableEl) return;
    const el = tableEl.querySelector("tbody");
    Sortable.create(el, {
      handle: ".moveSort",
      animation: 200,
      draggable: ".ant-table-row",
      onMove: (evt) => {
        newIndex = getElIndex(evt.related, flatTreeData.value, props.rowKey);
      },
      onEnd: (evt) => {
        if (flatTreeData.value.length == 1) return
        deleteEl(el);
        oldIndex = getElIndex(evt.item, flatTreeData.value, props.rowKey);
        const dragRow = flatTreeData.value[oldIndex];
        const relatedRow = flatTreeData.value[newIndex];

        if (dragRow.parentId && dragRow.parentId !== relatedRow.parentId) {
          message.warning("只能同层级内排序");
          return reRender();
        }

        if (!dragRow.children && !relatedRow.children) {
          const oldData = flatTreeData.value.splice(oldIndex, 1)[0];
          flatTreeData.value.splice(newIndex, 0, oldData);
        } else if (dragRow.children && !relatedRow.children) {
          const oldData = flatTreeData.value.splice(oldIndex, 1)[0];
          flatTreeData.value.splice(newIndex, 0, oldData);

          const flatChildren = [];
          getFlatNode(oldData.children || [], flatChildren);
          if (flatChildren.length > 0) {
            for (let i = 1, len = flatChildren.length; i <= len; i++) {
              let childData;
              if (newIndex < oldIndex) {
                // 有子元素的，子元素需要同样跟上来
                childData = flatTreeData.value.splice(oldIndex + i, 1)[0];
                flatTreeData.value.splice(newIndex + i, 0, childData);
              } else {
                // 有子元素的，子元素需要同样跟下来
                childData = flatTreeData.value.splice(oldIndex, 1)[0];
                flatTreeData.value.splice(newIndex, 0, childData);
              }
            }
          }
        } else if (!dragRow.children && relatedRow.children) {
          const oldData = flatTreeData.value.splice(oldIndex, 1)[0];
          flatTreeData.value.splice(newIndex, 0, oldData);

          if (newIndex > oldIndex) {
            // 有子元素的，子元素需要同样跟上来
            const flatChildren = [];

            getFlatNode(relatedRow.children || [], flatChildren);
            if (flatChildren.length > 0) {
              for (let i = 1, len = flatChildren.length; i <= len; i++) {
                const childData = flatTreeData.value.splice(newIndex + i, 1)[0];
                flatTreeData.value.splice(newIndex + i - 1, 0, childData);
              }
            }
          }
        } else if (dragRow.children && relatedRow.children) {
          const flatChildren = [];
          const oldData = flatTreeData.value.splice(oldIndex, 1)[0];
          if (newIndex < oldIndex) {
            flatTreeData.value.splice(newIndex, 0, oldData);

            // 有子元素的，子元素需要同样跟上来
            getFlatNode(oldData.children || [], flatChildren);
            if (flatChildren.length > 0) {
              for (let i = 1, len = flatChildren.length; i <= len; i++) {
                const childData = flatTreeData.value.splice(oldIndex + i, 1)[0];
                flatTreeData.value.splice(newIndex + i, 0, childData);
              }
            }
          } else {
            // relateRow的children数
            const relateFlatChildren = [];
            getFlatNode(relatedRow.children || [], relateFlatChildren);
            flatTreeData.value.splice(newIndex + relateFlatChildren.length, 0, oldData);
            // 有子元素的，子元素需要同样跟下来
            getFlatNode(oldData.children || [], flatChildren);
            if (flatChildren.length > 0) {
              for (let i = 1, len = flatChildren.length; i <= len; i++) {
                const childData = flatTreeData.value.splice(oldIndex, 1)[0];
                flatTreeData.value.splice(newIndex + relateFlatChildren.length, 0, childData);
              }
            }
          }
        }
        // 重新生成树的数据
        const data = getTreeData(flatTreeData.value, []);
        // console.log("index页面的Data=", data);
        reRender(data);
        setTimeout(() => {
          if (!props.isTreeData) {
            setData(treeTableData.value, 0);
            serial = 0;
          }
        }, 200);

        // 通过list传 

        let dragRowId = dragRow.pid // id
        let array = getBrotherNodes(data, dragRowId);
        // console.log('获取到的array',array)
        let mode = (newIndex - oldIndex) > 0 ? -1 : 1;


        let tabData = {
          sourceId: flatTreeData.value[oldIndex][props.rowKey],
          targetId: flatTreeData.value[newIndex][props.rowKey]
        };
        // 通过前后交换
        emit("drag", dragRow, relatedRow);
        // 向上: 1  向下: -1
        let params = {
          sourceId: dragRow[props.rowKey],
          targetId: relatedRow[props.rowKey]
        }
        emit("dragSortTable", { ...params, mode })
      }
    });
  });
};

const reRender = (data = null) => {
  const origin = data ? data : [].concat(treeTableData.value);
  treeTableData.value = [];
  nextTick(() => {
    treeTableData.value = origin;
  });
};

const expand = (expanded, record) => {
  nextTick(() => {
    setTreeStyle(uuid.value);
    initSortable();
    emit("expandTable", record);
  });
};

const rowClick = (record) => {
  return {
    onClick: (event) => {
      emit("customRow", record);
    }
  };
};

watch(
  treeTableData,
  () => {
    nextTick(() => {
      setTreeStyle(uuid.value);
    });
  },
  { deep: true, immediate: true }
);

watch(
  () => props.dataSource,
  (value) => {
    flatTreeData.value = [];
    treeTableData.value = JSON.parse(JSON.stringify(value));
    if (!props.isTreeData) {
      setData(treeTableData.value, 0);
      serial = 0;
    }
    // 想要拖拽表格数据必须有id
    transverseNode(treeTableData.value, 1, (node, level, parentNode) => {
      node.level = level;
      node.parentId = parentNode ? parentNode.id : -1;
    });
    getFlatNode(treeTableData.value, flatTreeData.value);
  },
  {
    deep: true,
    immediate: true,
  }
);

// 根据父盒子的大小改变
const scrollDefault = ref({
  y: 0,
  scrollToFirstRowOnChange: false,
});

const fresh = () => {
  if (!tableContainer.value) return;
  const height = tableContainer.value.clientHeight;
  scrollDefault.value.y = height - 90;
  nextTick(() => {
    if (props.scroll) {
      scrollDefault.value = { ...scrollDefault.value, ...props.scroll };
    }
    initSortable();
    setTreeStyle(uuid.value);
  });
};
watch(() => props.showSelection,
  (newValue) => {
    if (props.showSelection) initSortable()
  },
  {
    deep: true,
    immediate: true
  }
)
onMounted(() => {
  fresh();
  window.addEventListener("resize", () => {
    fresh();
  });
});
</script>

<style lang="less" scoped>
.table {
  width: 100%;
  height: 100%;
  margin-top: 10px;

  :deep(.iconfont) {
    font-size: 14px;
    margin-right: 8px;
  }

  :deep(.ant-table-thead .ant-table-cell) {
    font-weight: 600;
  }

  :deep(.ant-table-thead) {
    th {
      background: #fafafb;
    }
  }

  .null-iamge {
    width: 300px;
  }

  .null-text {
    margin: 20px 0;
    color: #333;
  }

  .one-td {
    position: relative;
  }

  :deep(.moveSort) {
    cursor: grab;
  }

  :deep(.sortable-chosen) {
    cursor: move !important;
  }

  :deep(.ant-table-cell > .ant-form-item) {
    margin: 0px;
  }

  :deep(.paddingLeft) {
    padding-left: 32px;
  }

  :deep(.drag) {
    height: 30px !important;
    overflow: hidden !important;
    background: #fff !important;
    opacity: 1 !important;
    border-radius: 10px;
    box-shadow: 0 0 4px 2px #ccc;
    padding: 10px 20px;
    display: flex;
    justify-content: center;
    align-items: center;
    margin-left: 80px !important;

    .ant-table-cell:first-child {
      display: block;
      padding: 0 20px !important;
      height: 30px !important;
      line-height: 30px;
      width: 100px !important;
      background: #fff !important;
      position: relative;
    }
  }

  :deep(.dragged-item) {
    opacity: 1 !important;
  }

  .ant-table-wrapper {
    height: 100%;
  }

  :deep(.ant-table-expanded-row-level-1 .ant-table-expanded-row-fixed) {
    padding: 0px 0px 0px 50px;
  }

  :deep(.ant-table-filter-column) {
    justify-content: flex-start;
  }

  :deep(.ant-table-column-sorters) {
    flex: unset;
    justify-content: flex-start;
  }

  :deep(.ant-table-column-title) {
    flex: inherit;
  }

  :deep(.ant-table-cell-fix-right) {
    border-left: 1px solid #e0e0e0;
  }

  :deep(.ant-table-row-indent) {
    padding: 0 !important;
  }
}
</style>
